home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / sound / rukq10.zip / X02.BAS < prev    next >
BASIC Source File  |  1993-02-15  |  9KB  |  278 lines

  1. DECLARE FUNCTION InitDevice% (device%, SIP AS ANY, IP AS ANY)
  2. DECLARE FUNCTION PickDevice% (SIP AS ANY, HighRate%)
  3.  
  4. REM $INCLUDE: 'RUCKDAC.BI'
  5.  
  6. '---------------------------------------
  7. 'SEE X02_71.BAS FOR BASIC7/VBDOS EXAMPLE
  8. '---------------------------------------
  9.  
  10. 'X02.BAS - load and play mod data file from DOS memory
  11. '
  12. '31-Jan-93 -chh
  13. 'C>bc X02 /o;
  14. 'C>link X02,X02.EXE,nul,RUCKDAC.LIB;
  15. ver$ = "[930131]"
  16.  
  17. DEFINT A-Z
  18.  
  19. 'The packs could be made global but passing them as paramters works
  20.  
  21. DIM SIP AS SysInfoPackTYPE
  22. DIM IP AS InitPackTYPE
  23. DIM LP AS LoadPackTYPE
  24. DIM SMP AS SetModPackTYPE
  25. DIM PBP AS PlaybackPackTYPE
  26. DIM XP AS XitPackTYPE
  27.  
  28. CLS
  29. PRINT "X02.BAS - RUCKUS-DAC play of MOD file example."; ver$
  30.  
  31. InIDE = -1     'since the IDE needs more than 2K available, use this to
  32.                'flag if operating in QB's ennvironment
  33.  
  34. 'RUCKDAC uses memory from the operating system pool
  35. 'since BASIC starts up claiming all memory, instruct it to return excess
  36. 'memory back to OS pool
  37.  
  38. nix& = SETMEM(700000)           'return to QB environment any previous release
  39. nix& = SETMEM(0)                'see how much is available
  40. nix& = nix& - 2100              'release all but 2K to operating system
  41.  
  42. IF InIDE THEN
  43.    nix& = nix& - 66000          'leave 64K more for IDE
  44.    XP.Func = ExitMod            'and shut down any loose ends
  45.    nix = RUCKDAC(XP)
  46. END IF
  47.  
  48. nix& = SETMEM(-nix&)            'this call does the actual release
  49.  
  50. 'pick device to use
  51.  
  52. devID = PickDevice(SIP, HighRate)'id system and get device to use
  53. IF devID < 0 THEN PRINT "Ended.": END
  54.  
  55. CLS
  56. LOCATE 5
  57.  
  58. 'initialize the selected device and register ExitDac via AtExitDac
  59.  
  60. stat = InitDevice(devID, SIP, IP)
  61. IF stat = 0 THEN
  62.    
  63.    'The following load and play example source is coded inline here
  64.    'to simplify readability -- but it's so easy to add things I just
  65.    'kept adding stuff, so take it slow if you don't follow at first
  66.  
  67.    'load file and setup playback parameters
  68.  
  69.    INPUT " MOD filename: ", filename$
  70.    PRINT "Playback rate:              ( 5000 to "; HighRate; ")";
  71.    LOCATE , 16
  72.    INPUT "", SampleRate
  73.    IF SampleRate < 5000 THEN SampleRate = 5000
  74.    IF SampleRate > HighRate THEN SampleRate = HighRate
  75.  
  76.    filename$ = filename$ + CHR$(0)        'DOS requires ASCIIZ name
  77.    LP.Func = LoadMod
  78.  
  79.    LP.FilenamePtrOff = SADD(filename$)    'QB format
  80.    LP.FilenamePtrSeg = VARSEG(filename$)
  81.    'LP.FilenamePtrOff = SADD(filename$)    'BASIC7 format
  82.    'LP.FilenamePtrSeg = SSEG(filename$)
  83.  
  84.    LP.StartPos = 0&     'start load at byte 0 of filename$
  85.    LP.LoadSize = 0&     'load entire file
  86.    LP.XMMflag = 0       'load into DOS
  87.    stat = RUCKDAC(LP)
  88.  
  89.    IF stat = 0 THEN
  90.    
  91.       'data is loaded, set up play parameters
  92.  
  93.       IF devID = 5 THEN         'just a quick bump of the Pro's out volumes
  94.          SPP.Func = SetVolMainSBP
  95.          SPP.Volume = &HF0F
  96.          stat = RUCKDAC(SPP)
  97.  
  98.          SPP.Func = SetVolVocSBP
  99.          V = &HF0F
  100.          stat = RUCKDAC(SPP)   'see RUCKUS-MIDI for AdLib/FM volume adjust
  101.       END IF
  102.  
  103.       SMP.VolCh1 = 255
  104.       SMP.VolCh2 = 255
  105.       SMP.VolCh3 = 255
  106.       SMP.VolCh4 = 255
  107.       SMP.Func = SetVolumeMod
  108.       stat = RUCKDAC(SMP)
  109.    
  110.       IF devID < 5 THEN SMP.Stereo = 0 ELSE SMP.Stereo = 1
  111.       SMP.Func = SetStereoMod
  112.       stat = RUCKDAC(SMP)
  113.  
  114.       SMP.IntRate = SampleRate  'IntRate and SliceAdj set with SetIntRateMod
  115.  
  116.       'The SBPro doubles the sample rate when doing stereo output so
  117.       'here we double the requested rate to rate needed by SBPRO. This
  118.       'should be done _AFTER_ the SetStereoMod call above.
  119.  
  120.       IF SMP.Stereo THEN        'this routine converts sample rates >32K
  121.          t& = 2& * SampleRate   'to a signed integer value
  122.          IF t& > 32767 THEN t& = t& - 65536
  123.          SMP.IntRate = t&
  124.       END IF
  125.  
  126.       SMP.SliceAdj = 1          'fill DMA buffer 1 byte at a time (to 4K)
  127.       SMP.Func = SetIntRateMod  'error checking typically should always
  128.       stat = RUCKDAC(SMP)       'be performed but not here for clarity
  129.  
  130.  
  131.       ''SMP.FastMode = 0         'on slow CPUs (XTs) set this to 1
  132.       ''SMP.Func = SetFastMod    'and call SetFastMod function
  133.       ''stat = RUCKDAC(SMP)
  134.  
  135.       'if device is a Sound Blaster, use DMA+FG, else timer-0 FG
  136.  
  137.       PBP.Func = PlayMod
  138.       IF devID < 4 THEN PBP.Mode = 0 ELSE PBP.Mode = 2
  139.  
  140.       'for timer-0 background play set PBP.Mode = 1 and for DMA background
  141.       'play set PBP.Mode = 3 -- you must also poll dac@endmod in the
  142.       'RUCKUS-DAC data area (offset +14) and wait until it is non-zero
  143.       'to determine if mod playback has completed
  144.  
  145.       'for complete compatibilty mod play is done as a foreground task
  146.       'in this example
  147.  
  148.       PRINT "Playing as a foreground ";
  149.       IF devID >= 4 THEN PRINT "DMA";  ELSE PRINT "TIMER-0";
  150.       PRINT " task ";
  151.       IF devID = 5 THEN PRINT "in ((STEREO)) ";
  152.       PRINT "at"; SampleRate; "Hz mix rate"
  153.       PRINT
  154.       PRINT "Press CTRL-ALT to end or wait until tune is over."
  155.  
  156.       'note that the PC speaker playback may sound better if the
  157.       'keyboard pause button is activated, try it
  158.  
  159.       PBP.XMMhandle = 0
  160.       'Note that PBP.LoadPtrOff/Seg is not used with mod playback since
  161.       'only one mod can be in memory at a time
  162.       PBP.BufferSize = 4096           'each DMA buffer (2) is this size
  163.       stat = RUCKDAC(PBP)             'and allocated for SBs only (2048-64K)
  164.  
  165.       IF stat = 0 THEN
  166.  
  167.          'Playing in the foreground, wait until done or Ctrl-Alt pressed.
  168.          'Won't get here until CTRL-ALT is pressed or end of tune
  169.  
  170.          'end play
  171.  
  172.          XP.Func = EndMod
  173.          stat = RUCKDAC(XP)
  174.  
  175.          'to release memory used by LoadMod use ExitMod
  176.  
  177.       ELSE
  178.          PRINT "Play of "; filename$; "failed, stat:"; stat
  179.       END IF
  180.  
  181.    ELSE
  182.       PRINT "Load of "; filename$; "failed, stat:"; stat
  183.    END IF
  184.  
  185. ELSE
  186.    PRINT "InitDevice failed, stat:"; stat
  187. END IF
  188.  
  189. 'shut down RUCKDAC and end program
  190.  
  191. XP.Func = ExitMod
  192. nix = RUCKDAC(XP)
  193. PRINT "  Done, stat:"; stat
  194. nix& = SETMEM(700000)   'return to QB environment any previous release
  195. END
  196.  
  197. FUNCTION InitDevice (device, SIP AS SysInfoPackTYPE, IP AS InitPackTYPE)
  198.  
  199. 'Initialize RUCKDAC and device and register ExitMod with _atexit
  200.  
  201. DIM XP AS XitPackTYPE   'local use for AtExitMod
  202.  
  203. IP.Func = InitDac
  204. IP.DeviceID = device
  205. SELECT CASE device
  206. CASE 0: IP.IOport = 0:          IP.IRQline = SIP.D0IRQ: IP.DMAch = SIP.D0DMA
  207. CASE 1: IP.IOport = SIP.D1port: IP.IRQline = SIP.D1IRQ: IP.DMAch = SIP.D1DMA
  208. CASE 2: IP.IOport = SIP.D2port: IP.IRQline = SIP.D2IRQ: IP.DMAch = SIP.D2DMA
  209. CASE 3: IP.IOport = 0:          IP.IRQline = SIP.D3IRQ: IP.DMAch = SIP.D3DMA
  210. CASE 4: IP.IOport = SIP.D4port: IP.IRQline = SIP.D4IRQ: IP.DMAch = SIP.D4DMA
  211. CASE 5: IP.IOport = SIP.D5port: IP.IRQline = SIP.D5IRQ: IP.DMAch = SIP.D5DMA
  212. END SELECT
  213. stat = RUCKDAC(IP)
  214.  
  215. IF stat = 0 THEN
  216.  
  217.    'register ExitMod and notify if failure occured, non-fatal and unlikely
  218.  
  219.    XP.Func = AtExitMod
  220.    stat2 = RUCKDAC(XP)
  221.    IF stat2 THEN INPUT "AtExitMod failed, press ENTER to continue", a$
  222.  
  223. END IF
  224.  
  225. InitDevice = stat
  226.  
  227. END FUNCTION
  228.  
  229. FUNCTION PickDevice (SIP AS SysInfoPackTYPE, HighRate)
  230.  
  231. 'RUCKDAC SysInfoDac lib routine called to find available devices
  232. 'user prompted which device to use (0-5), -1 means no valid selection
  233. 'HighRate returned which is effective top-end of device
  234.  
  235. DIM device AS INTEGER
  236.  
  237. device = -1
  238. HighRate = 5000
  239.  
  240. SIP.Func = SysInfoDac
  241. stat = RUCKDAC(SIP)
  242. IF stat = 0 THEN
  243.  
  244.    'list devices that are available
  245.    PRINT
  246.    PRINT "0. End program"
  247.    PRINT "1. PC speaker at port 42h"
  248.    IF SIP.Device1 THEN PRINT "2. LPT-DAC on LPT1, port "; HEX$(SIP.D1port); "h"
  249.    IF SIP.Device2 THEN PRINT "3. Disney Sound System port "; HEX$(SIP.D2port); "h"
  250.    PRINT
  251.    IF SIP.Device3 THEN PRINT "4. AdLib Music Synthesizer Card, port 388h"
  252.    IF SIP.Device4 THEN PRINT "5. Sound Blaster, port "; HEX$(SIP.D4port); "h, IRQ"; SIP.D4IRQ; "and DMA 1"
  253.    IF SIP.Device5 THEN PRINT "6. Sound Blaster Pro ((STEREO)), port "; HEX$